package com.platform.rpc.intercepter;

import com.sun.org.apache.xerces.internal.dom.ElementNSImpl;
import org.apache.cxf.binding.soap.SoapHeader;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.saaj.SAAJInInterceptor;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.NodeList;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;

/**
 * WebService服务安全验证
 * User: wangyanginfo
 * Date: 13-1-16
 * Time: 下午4:23
 */
public class SOAPAuthIntercepter extends AbstractPhaseInterceptor<SoapMessage> {

	private SAAJInInterceptor saaIn = new SAAJInInterceptor();
	private String namespaceURI = "http://www.360buy.com";
	private String localPart = "AuthenticationHeader";

	private AuthHeader authHeader;

	public SOAPAuthIntercepter() {
		//定义什么阶段被拦截
		super(Phase.PRE_PROTOCOL);
		getAfter().add(SAAJInInterceptor.class.getName());
	}

	@Override
	public void handleMessage(SoapMessage message) throws Fault {
		System.out.println("=========>message:" + message);
		if (!checkQnameHeader(message) && !checkMessageHeader(message)) {
			throw new IllegalArgumentException("The Token wrong!");
		}
	}

	/**
	 * 校验指定的Qname头
	 *
	 * @param message
	 * @return
	 */
	private boolean checkQnameHeader(SoapMessage message) {
		SoapHeader header = (SoapHeader) message.getHeader(new QName(namespaceURI, localPart));
		if (header == null) {
			return false;
		}
		ElementNSImpl ei = (ElementNSImpl) header.getObject();
		String token;
		try {
			token = ei.getFirstChild().getFirstChild().getTextContent();
			return authHeader.checkTokenValue(token);
		} catch (Exception e) {
			throw new IllegalArgumentException("Method --> checkQnameHeader error", e);
		}
	}

	/**
	 * 校验消息头
	 *
	 * @param message
	 * @return
	 */
	private boolean checkMessageHeader(SoapMessage message) {
		try {
			SOAPMessage mess = message.getContent(SOAPMessage.class);
			if (mess == null) {
				saaIn.handleFault(message);
				mess = message.getContent(SOAPMessage.class);
			}
			//获得SOAPHeader
			SOAPHeader head = mess.getSOAPHeader();
			if (head == null) return false;

			//获得这个名称的NodeList
			NodeList nodes = head.getElementsByTagName(localPart);
			if (nodes == null) return false;

			//取出来判断是否相等
			String token = "";
			for (int i = 0; i < nodes.getLength(); i++) {
				token += nodes.item(i).getTextContent();
			}

			return authHeader.checkTokenValue(token);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	public AuthHeader getAuthHeader() {
		return authHeader;
	}

	public void setAuthHeader(AuthHeader authHeader) {
		this.authHeader = authHeader;
	}
}
